package com.indexingsystem.boss.utils;

import java.text.DecimalFormat;
import java.text.NumberFormat;

/**
 * 
 * 62进制数字,数字转换工具类.
 *
 * @author Administrator
 *
 */
public class NumberUtils {
	/**
	 * 62个字母和数字，含大小写
	 */
	public static final char[] N62_CHARS = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E',
			'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
			'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u',
			'v', 'w', 'x', 'y', 'z' };
	/**
	 * 36个小写字母和数字
	 */
	public static final char[] N36_CHARS = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e',
			'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z' };
	/**
	 * 长整型用N36表示的最大长度
	 */
	public static final int LONG_N36_LEN = 13;
	/**
	 * 长整型用N62表示的最大长度
	 */
	public static final int LONG_N62_LEN = 11;

	/**
	 * 把一个浮点型数字转换成字符串
	 * 
	 * @param num
	 *            要转换的浮点型数值
	 * @return 带小数点的字符串
	 */
	public static String toString(double num) {
		NumberFormat f = NumberFormat.getInstance();
		if (f instanceof DecimalFormat) {
			((DecimalFormat) f).setDecimalSeparatorAlwaysShown(true);
		}
		f.setParseIntegerOnly(true);
		return f.format(num);
	}

	/**
	 * 把字符串转换成浮点型数字，转换失败就返回0.0
	 * 
	 * @param str
	 *            转换的字符串
	 * @return 转换后的浮点数字
	 */
	public static double toDouble(Object str) {
		return toDouble((String) str, 0.0);
	}
	
	  /**
     * 指定给定的double的小数位数
     * 
     * @param num 浮点数
     * @param fractionDigit 小数位数
     * @return 指定小数位数的浮点数
     */
    public static double toDouble(double num, int fractionDigit) {
        String d = toString(num, fractionDigit);
        return toDouble(d, 0.00);
    }
    
    
    /**
     * 数字格式化对象
     */
    private final static NumberFormat theNumberFormatter = NumberFormat
            .getNumberInstance();

    /**
     * 判断一个字符串是否为long型
     * 
     * @param str 被判断的字符串
     * @return =true 是long型的字符串 =false 不是long型的字符串
     */
    public static boolean isLong(String str) {
        @SuppressWarnings("unused")
        long l;
        try {
            l = Long.parseLong(str);
        } catch(Exception e) {
            return false;
        }
        return true;
    }

    /**
     * 判断一个字符串是否为int型
     * 
     * @param str 被判断的字符串
     * @return =true 是int型的字符串 =false 不是int型的字符串
     */
    public static boolean isInteger(String str) {
        try {
            Integer.parseInt(str);
        } catch(Exception e) {
            return false;
        }
        return true;
    }

    /**
     * 把浮点型转换成含有指定小数点位数的字符串
     * 
     * @param num 浮点型数字
     * @param fractionDigit 小数点位数
     * @return 带指定小树位数的浮点字符串
     */
    public static String toString(double num, int fractionDigit) {
        NumberFormat nf = NumberFormat.getInstance();
        nf.setMinimumIntegerDigits(1);
        nf.setMinimumFractionDigits(fractionDigit);
        nf.setMaximumFractionDigits(fractionDigit);

        return nf.format(num);
    }

    /**
     * 把一个字符串转换成整数
     * 
     * @param str 整型字符串
     * @return 整型数字
     */
    public static int toInt(String str) {
        return toInt(str, 0);
    }
    
    /**
     * 把一个Object串转换成整数
     * 
     * @param str 整型字符串
     * @return 整型数字
     */
    public static int toInt(Object str) {
        return toInt(str+"", 0);
    }

    /**
     * 把一个字符串转换成整数對象
     * 
     * @param str 整型字符串
     * @return 整型数字
     */
    public static Integer toIntObject(String str) {
        return new Integer(str);
    }

    /**
     * 把一个字符串转换成整数，如果字符串為空就返回指定整形值
     * 
     * @param str 整型字符串
     * @param defaultValue 默認的整型值
     * @return 整型数字
     */
    public static int toInt(String str, int defaultValue) {
        if(StringUtil.empty(str)) {
            return defaultValue;
        }
        try {
            if(!isInteger(str)) {
                return defaultValue;
            }
            return toRawInt(str);
        } catch(Exception e) {
            e.printStackTrace();
            return defaultValue;
        }
    }

    /**
     * 把一个字符串转换成整数
     * 
     * @param str 要转换的字符串
     * @return 整数
     * @throws java.lang.Exception 转换错误的返回值
     */
    public static int toRawInt(String str) throws Exception {
        return Integer.parseInt(str.trim());
    }

    public static int toFormattedInt(String str) {
        return toFormattedInt(str, 0);
    }

    /**
     * 把一个字符串转换成整数，如果字符串为空或转换错误就返回缺省值
     * 
     * @param str 被转换的字符串
     * @param defaultValue 缺省值
     * @return 转换后的整数
     */
    public static int toFormattedInt(String str, int defaultValue) {
        if(StringUtil.empty(str)) {
            return defaultValue;
        }
        try {
            return toRawFormattedInt(str);
        } catch(Exception e) {
            e.printStackTrace();
            return defaultValue;
        }
    }

    /**
     * 把一个字符串转换成整数
     * 
     * @param str 被转换的字符串
     * @return 转换后的整数
     * @throws java.lang.Exception 转换错误
     */
    public static int toRawFormattedInt(String str) throws Exception {
        return Integer
                .parseInt(theNumberFormatter.parse(str.trim()).toString());
    }

    
    /**
     * 把字符串转换为long型，转换失败就返回0L
     * 
     * @param str 需要转换的字符串
     * @return 转换后的Long型数字
     */
    public static long toLong(Object str) {
        return toLong(str+"");
    }
    /**
     * 把字符串转换为long型，转换失败就返回0L
     * 
     * @param str 需要转换的字符串
     * @return 转换后的Long型数字
     */
    public static long toLong(String str) {
        return toLong(str, 0L);
    }

    /**
     * 把字符串转换为Long型
     * 
     * @param str 需要转换的字符串
     * @return 转换后的long型数字
     */
    public static Long toLongObject(String str) {
        return new Long(str.trim());
    }

    /**
     * 把字符串转换为Long型，转换失败就返回指定缺省值
     * 
     * @param str 需要转换的字符串
     * @param defaultValue 指定的缺省字符串
     * @return 转换后的Long型数字
     */
    public static Long toLongObject(String str, long defaultValue) {
        if(StringUtil.empty(str)) {
            return new Long(defaultValue);
        }
        return new Long(str.trim());
    }
    
    /**
     * 把object转换为Long型，转换失败就返回指定缺省值
     * 
     * @param str 需要转换的字符串
     * @param defaultValue 指定的缺省字符串
     * @return 转换后的Long型数字
     */
    public static Long toLong(Object object, long defaultValue) {
    	String str = object == null?"":object+"";
        return toLong(str, defaultValue);
    }

    /**
     * 把字符串转换为long型，转换失败就返回指定缺省值
     * 
     * @param str 需要转换的字符串
     * @param defaultValue 指定的缺省字符串
     * @return 转换后的long型数字
     */
    public static long toLong(String str, long defaultValue) {
        if(StringUtil.empty(str)) {
            return defaultValue;
        }
        try {
            return toRawLong(str);
        } catch(Exception e) {
            e.printStackTrace();
            return defaultValue;
        }
    }

    /**
     * 把字符串转换成long型
     * 
     * @param str 需要转换的字符串
     * @return 转换后的long型数字
     * @throws java.lang.Exception 转换失败错误
     */
    public static long toRawLong(String str) throws Exception {
        return Long.parseLong(str.trim());
    }

    /**
     * 把字符串转换为long型，转换错误就返回0L
     * 
     * @param str 需要转换的字符串
     * @return 转换后的字符串
     */
    public static long toFormattedLong(String str) {
        return toFormattedLong(str, 0L);
    }

    /**
     * 把字符串转换成long型，转换错误就返回指定的缺省值
     * 
     * @param str 需要转换的字符串
     * @param defaultValue 指定的缺省值
     * @return 转换后的long型数字
     */
    public static long toFormattedLong(String str, long defaultValue) {
        if(StringUtil.empty(str)) {
            return defaultValue;
        }
        try {
            return toRawFormattedLong(str);
        } catch(Exception e) {
            e.printStackTrace();
            return defaultValue;
        }
    }

    /**
     * 把字符串转换成long型
     * 
     * @param str 转换的字符串
     * @return 转换后的long型数字
     * @throws java.lang.Exception 转换失败的错误
     */
    public static long toRawFormattedLong(String str) throws Exception {
        return Long.parseLong(theNumberFormatter.parse(str.trim()).toString());
    }



    /**
     * 把字符串转换为浮点型，转换失败就返回指定缺省值
     * 
     * @param str 需转换的字符串
     * @param defaultValue 指定的缺省值
     * @return 转换好的浮点数字
     */
    public static double toDouble(String str, double defaultValue) {
        if(StringUtil.empty(str)) {
            return defaultValue;
        }
        try {
            return toRawDouble(str);
        } catch(Exception e) {
            e.printStackTrace();
            return defaultValue;
        }
    }
    
    /**
     * 四舍五入
     * @param value
     * @param format 格式位数，"0.00"
     */
    public static double toDouble(double value,String format){
    	DecimalFormat df=new DecimalFormat(format);
        return new Double(df.format(value));
    }

    /**
     * 把字符串转换成浮点型数字
     * 
     * @param str 转换的字符串
     * @return 转换后的浮点数字
     * @throws Exception 转换失败错误
     */
    public static double toRawDouble(String str) throws Exception {
        return Double.parseDouble(str.trim());
    }

    /**
     * 把字符串转换成浮点型数字，转换失败就返回0.0
     * 
     * @param str 转换的字符串
     * @return 转换后的浮点数字
     */
    public static double toFormattedDouble(String str) {
        return toFormattedDouble(str, 0.0);
    }

    /**
     * 把字符串转换为浮点型数字，转换失败就返回缺省值
     * 
     * @param str 需要转换的字符串
     * @param defaultValue 转换的缺省值
     * @return 转换后的浮点型数字
     */
    public static double toFormattedDouble(String str, double defaultValue) {
        if(StringUtil.empty(str)) {
            return defaultValue;
        }
        try {
            return toRawFormattedDouble(str);
        } catch(Exception e) {
            e.printStackTrace();
            return defaultValue;
        }
    }

    /**
     * 把字符串转换为浮点型数字
     * 
     * @param str 需要转换的字符串
     * @return 浮点型数字
     * @throws java.lang.Exception 转换错误
     */
    public static double toRawFormattedDouble(String str) throws Exception {
        return Double.parseDouble(theNumberFormatter.parse(str.trim())
                .toString());
    }
    
    /**
     * @Method toFloat方法.<br>
     * @Description TODO 将Object转换为Float
     * @param str
     * @return
     */
    public static float toFloat(Object str) {
        return toFloat(str+"", 0.0f);
    }
    /**
     * @Method toFloat方法.<br>
     * @Description TODO 把字符串转换为浮点型，转换失败就返回指定缺省值
     * @param str 需转换的字符串
     * @param defaultValue 指定的缺省值
     * @return 转换好的浮点数字
     */
    public static float toFloat(String str, float defaultValue) {
        if(StringUtil.empty(str)) {
            return defaultValue;
        }
        try {
            return toRawFloat(str);
        } catch(Exception e) {
            e.printStackTrace();
            return defaultValue;
        }
    }
    
    /**
     * @Method toRawFloat方法.<br>
     * @Description TODO 把字符串转换成浮点型数字
     * @param str 转换的字符串
     * @return 转换后的浮点数字
     * @throws Exception 转换失败错误
     */
    public static float toRawFloat(String str) throws Exception {
        return Float.parseFloat(str.trim());
    }
    /**
     * 把整数数组转化成整数对象数组
     * 
     * @param set 整数数组
     * @return 证书对象数组
     */
    public static Integer[] toIntegerObjectSet(int[] set) {
        if(set == null) {
            return null;
        }
        Integer[] s = new Integer[set.length];
        for(int i = 0; i < set.length; i++) {
            s[i] = new Integer(set[i]);
        }
        return s;
    }

    /**
     * 将字符串按照delim分隔符进行分割，并转化成数组
     * 
     * @param str 字符串
     * @param delim 分隔符
     * @return 整数数组
     */
    public static int[] splitToIntSet(String str, String delim) {
        int[] intSet = new int[0];
        String[] strSet = StringUtil.split(str, delim);
        if(null == strSet) {
            return intSet;
        }
        for(int i = 0; i < strSet.length; i++) {
            try {
                intSet = ArrayUtil.addIntArray(intSet, toRawInt(strSet[i]));
            } catch(Exception e) {
            }
        }
        return intSet;
    }

    /**
     * 将set数组合并成以delim为分割符的字符串
     * 
     * @param set 整型数组
     * @param delim 分割符
     * @return 带delim分隔符的字符串
     */
    public static String join(int[] set, String delim) {
        if((null == set) || (set.length <= 0)) {
            return "";
        }
        StringBuffer sb = new StringBuffer();
        sb.append(set[0]);
        for(int i = 1; i < set.length; i++) {
            sb.append(delim);
            sb.append(set[i]);
        }
        return sb.toString();
    }


    /**
     * 调整整数的范围
     * 
     * @param old 被调整的整数值
     * @param min 调整最小值
     * @param max 调整最大值
     * @return 调整后的整数
     */
    public static final int adjustRange(int old, int min, int max) {
        if(old < min) {
            old = min;
        }
        if(old > max) {
            old = max;
        }
        return old;
    }

    /**
     * 调整整数的范围
     * 
     * @param old 被调整的整数值
     * @param min 调整最小值
     * @return 调整后的整数
     */
    public static final int adjustMinRange(int old, int min) {
        if(old < min) {
            old = min;
        }
        return old;
    }

    /**
     * 调整整数的范围
     * 
     * @param old 被调整的整数值
     * @param max 调整最大值
     * @return 调整后的整数
     */
    public static final int adjustMaxRange(int old, int max) {
        if(old > max) {
            old = max;
        }
        return old;
    }



    /**
     * 把阿拉伯数字转换成大写数字.<br>
     *方法名:parseNumber方法.<br>
     * 
     *@param num：小写阿拉伯数字
     *@return 转换后的数字
     */
    public final static String parseNumber(int num) {
        String[] digit = new String[] { "0", "一", "二", "三", "四", "五", "六", "七",
                "八", "九" };
        String[] unit = new String[] { "#", "十", "百", "千", "万", "十", "百", "千",
                "亿" };
        StringBuffer sb = new StringBuffer();
        int t, unitIndex = 0;
        while (num > 0) {
            t = num % 10;
            if(t > 0 || unitIndex % 4 == 0)
                sb.append(unit[unitIndex]);
            if(!(unitIndex == 0 && t == 0))
                sb.append(digit[t]);
            unitIndex += 1;
            num = num / 10;
        }
        return sb.reverse().toString().replaceAll("0{2,}", "0").replaceAll(
                "0万", "万").replaceFirst("0#", "").replaceFirst("#", "");
    }
    
	

	/**
	 * 将数组转换为字符串。
	 * 
	 * @param array
	 *            长整型数组
	 * @return 字符串
	 */
	public final static String toString(long[] array) {
		if (null == array) {
			return "count=0:[]";
		}

		String s = "count=" + array.length + ":[ ";
		for (int i = 0; i < array.length; i++) {
			if (i > 0) {
				s += ", ";
			}
			s += array[i];
		}
		s += " ]";
		return s;
	}

	/**
	 * 将整型数组转换成字符串
	 * 
	 * @param array
	 *            整型数组
	 * @return 字符串
	 */
	public final static String toString(int[] array) {
		if (null == array) {
			return "count=0:[]";
		}

		String s = "count=" + array.length + ":[ ";
		for (int i = 0; i < array.length; i++) {
			if (i > 0) {
				s += ", ";
			}
			s += array[i];
		}
		s += " ]";
		return s;
	}



	/**
	 * 长整型转换成字符串
	 * 
	 * @param l
	 * @param chars
	 * @return
	 */
	private static StringBuilder longToNBuf(long l, char[] chars) {
		int upgrade = chars.length;
		StringBuilder result = new StringBuilder();
		int last;
		while (l > 0) {
			last = (int) (l % upgrade);
			result.append(chars[last]);
			l /= upgrade;
		}
		return result;
	}

	/**
	 * 长整数转换成N62
	 * 
	 * @param l
	 * @return
	 */
	public static String longToN62(long l) {
		return longToNBuf(l, N62_CHARS).reverse().toString();
	}

	/**
	 * 长整型转换成N36
	 * 
	 * @param l
	 * @return
	 */
	public static String longToN36(long l) {
		return longToNBuf(l, N36_CHARS).reverse().toString();
	}

	/**
	 * 长整数转换成N62
	 * 
	 * @param l
	 * @param length
	 *            如不足length长度，则补足0。
	 * @return
	 */
	public static String longToN62(long l, int length) {
		StringBuilder sb = longToNBuf(l, N62_CHARS);
		for (int i = sb.length(); i < length; i++) {
			sb.append('0');
		}
		return sb.reverse().toString();
	}

	/**
	 * 长整型转换成N36
	 * 
	 * @param l
	 * @param length
	 *            如不足length长度，则补足0。
	 * @return
	 */
	public static String longToN36(long l, int length) {
		StringBuilder sb = longToNBuf(l, N36_CHARS);
		for (int i = sb.length(); i < length; i++) {
			sb.append('0');
		}
		return sb.reverse().toString();
	}

	/**
	 * N62转换成整数
	 * 
	 * @param n62
	 * @return
	 */
	public static long n62ToLong(String n62) {
		return nToLong(n62, N62_CHARS);
	}

	/**
	 * N36转换成整数
	 * 
	 * @param n36
	 * @return
	 */
	public static long n36ToLong(String n36) {
		return nToLong(n36, N36_CHARS);
	}

	private static long nToLong(String s, char[] chars) {
		char[] nc = s.toCharArray();
		long result = 0;
		long pow = 1;
		for (int i = nc.length - 1; i >= 0; i--, pow *= chars.length) {
			int n = findNIndex(nc[i], chars);
			result += n * pow;
		}
		return result;
	}

	private static int findNIndex(char c, char[] chars) {
		for (int i = 0; i < chars.length; i++) {
			if (c == chars[i]) {
				return i;
			}
		}
		throw new RuntimeException("N62(N36)非法字符：" + c);
	}

	public static void main(String[] args) {
		System.out.println(longToN62(Long.MAX_VALUE));
	}
}